/*
 * Copyright (C) 2011 Mette Bank, Rikke Jensen, Kenneth Brodersen, Thomas Pedersen
 * 
 * This file is part of digiPECS.
 * 
 * digiPECS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * digiPECS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with digiPECS.  If not, see <http://www.gnu.org/licenses/>.
 */

package sw6.digipecs.database;

import sw6.digipecs.exceptions.DatabaseException;
import sw6.digipecs.exceptions.IDNotFoundException;
import sw6.digipecs.exceptions.NotSupportedException;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Database helper class. This class encapsulates all database related tasks. The class should be used as follows:
 * - First create a new instance of the class. This instance may be reused, so save it in a field variable is recommended.
 * - Run open() on the instance to open the database.
 * - Run the methods desired.
 * - Run close() to close the database again.
 * 
 * \anchor dbadapterexample
 * An example of using this class (note \c mDb is a field, instantiated in the constructor):
\code

// Open database and run query
mDb.open();
Cursor cursor = mDb.fetchSentenceBoardState();
cursor.moveToFirst();

while (!sbCursor.isAfterLast()) {
   // Retrieve data from the database
   final int index = mDb.getSentenceBoardStateIndex(sbCursor);
   final String uri = mDb.getSentenceBoardStateUri(sbCursor);
   final String text = mDb.getSentenceBoardStateText(sbCursor);

   // Use the data
   final ExtImage restoredImage = new ExtImage(uri, text);
   mImagesInBoard.set(index, restoredImage);
   sbCursor.moveToNext();
}

// Close cursor and database
cursor.close();
mDb.close();

\endcode
 * 
 * \see \ref upgradedatabase on how to change database design.
 * 
 * @author sw6.digipecs
 *
 */
public class DBAdapter extends SQLiteOpenHelper {
	// TODO Ideas for this class:
	// - Throw an notOpenException or something, if fetching data from an non-open database (else a null pointer exception is thrown, difficult to know what that is!!!)
	// - Make all get methods static
	
	/**
	 * \page upgradedatabase How to upgrade database
	 * This is an how to guide on how upgrading the database design is done probably.
	 * Please follow these instructions to avoid issues with upgrading the databases on costumer units.
	 * All codes changes are made to the DBAdapter Class
	 * 
	 * \section sec1 Database version number
	 * The DATABASE_VERSION integer should be increased with 1 every time the database is upgraded, to allow detection of out of date databases.
	 * 
	 * \section sec2 Table definitions
	 * Next the table definitions lines should be updated as desired. The naming-scheme for definition lines is as follows:
	 * - \c DB_TableName contains the name of the table itself. Replace TableName with a name describing the table.
	 * - \c DB_TableName_ColumnName contains the name of the column. Replace ColumnName with a name describing the column. 
	 * - \c DB_TableName_ColumnName_ contains the column definition. This is equivalent to the sql definition.
	 * - \c DB_TableName_ contains the CREATE sql command for the table, please use the above names to construct this command. e.g. <tt> "CREATE TABLE " + DB_TableName + " (" + DB_TableName_ColumnName + " " + DB_TableName_ColumnName_ + ");" </tt>
	 * 
	 * \section sec3 Table creation
	 * If a new table is being added to the database, a new line should be added to the onCreate() method.
	 * The line should simply execute the creation line, e.g. <tt> db.execSQL(DB_TableName_); </tt>
	 * 
	 * \section sec4 Table upgrade
	 * Each of the previous version numbers should have a case in the switch statement.
	 * In this case, commands should be run which updates the database from the old version to the new version.
	 * ALL use of \c DB_* names is PROHIBITED, as these only contains the \e newest version of the database, and the upgrade commands needs the \e old version.
	 * Please avoid use of calling \c onCreate() here and the use of \c break after the case, so the versions are continuously upgraded upwards until the current version is reached.
	 * However, these may be useful tricks to avoid use of \c DB_* names.
	 * 
	 * New tables should also add a line to the \c default case where they drop their table if it exists.
	 * 
	 * \section sec5 Helper methods
	 * The class also contains a set of helper methods, which inserts, updates, deletes, and queries values in the database. These methods should be updated or added accordingly to your needs.
	 * 
	 * One common design is to have the query methods return a cursor, and then add a set for methods which extracts values from this cursor, using the \c DB_* names.
	 */
	
	// Overall settings
	private static final String DATABASE_NAME = "digipecs_data";
	private static final int DATABASE_VERSION = 14;
	private static final String LOG_TEXT = "sw6.digipecs.db";
	private static final int DEFAULT_SITUATION_LOCATION = 0;
	
	public static final int FALSE = 0;
	public static final int TRUE  = 1;
	// -------------------------------------------------------------------------
	// Table Definitions
	// - Updates here should be reflected in onCreate() and onUpgrade() as well
	// - Remember to update version number above
	// -------------------------------------------------------------------------

	// Picture table definition
	public  static final String DB_Picture = "picture";
	public  static final String DB_Picture_ID = "picture_id";
	private static final String DB_Picture_ID_ = "INTEGER PRIMARY KEY AUTOINCREMENT";	
	public  static final String DB_Picture_ImageText = "image_text";
	private static final String DB_Picture_ImageText_ = "TEXT NOT NULL";
	public  static final String DB_Picture_ImagePath = "image_path";
	private static final String DB_Picture_ImagePath_ = "TEXT NOT NULL";
	public  static final String DB_Picture_ImageSound = "image_sound";
	private static final String DB_Picture_ImageSound_ = "TEXT";
	private static final String DB_Picture_ = "CREATE TABLE " + DB_Picture + " (" +
											  DB_Picture_ID + " " + DB_Picture_ID_ + ", " +
											  DB_Picture_ImageText + " " + DB_Picture_ImageText_ + ", " +
											  DB_Picture_ImagePath + " " + DB_Picture_ImagePath_ + ", " +
											  DB_Picture_ImageSound	+ " " + DB_Picture_ImageSound_ + ");";
	
	// Sentence Board table definition
	public  static final String DB_SentenceBoard = "sentenceboard";
	public  static final String DB_SentenceBoard_Index = "image_index";
	private static final String DB_SentenceBoard_Index_ = "INTEGER PRIMARY KEY";
	public  static final String DB_SentenceBoard_Picture_ID = "sentenceboard_picture_id";
	private static final String DB_SentenceBoard_Picture_ID_= "INTEGER REFERENCES " + DB_Picture + " (" + DB_Picture_ID + ")";
	public  static final String DB_SentenceBoard_Lock = "lock";
	private static final String DB_SentenceBoard_Lock_ = "INTEGER NOT NULL";
	private static final String DB_SentenceBoard_ = "CREATE TABLE " + DB_SentenceBoard + " (" +
													   DB_SentenceBoard_Index + " " + DB_SentenceBoard_Index_ + ", " +
													   DB_SentenceBoard_Picture_ID + " " + DB_SentenceBoard_Picture_ID_ + ", " + 
													   DB_SentenceBoard_Lock + " " + DB_SentenceBoard_Lock_ + ");";
	// Situation table definition
	public  static final String DB_Situation = "situation";
	public  static final String DB_Situation_ID = "situation_id";
	private static final String DB_Situation_ID_ = "INTEGER PRIMARY KEY AUTOINCREMENT";
	public  static final String DB_Situation_Name = "situation_name";
	private static final String DB_Situation_Name_ = "TEXT";
	private static final String DB_Situation_ = "CREATE TABLE " + DB_Situation + " (" +
												   DB_Situation_ID + " " + DB_Situation_ID_ + ", " +
												   DB_Situation_Name + " " + DB_Situation_Name_ + ");";
	// Picture Situation table definition
	public  static final String DB_PictureSituation = "picturesituation";
	public  static final String DB_PictureSituation_Picture_ID = "picturesituation_picture_id";
	private static final String DB_PictureSituation_Picture_ID_ = "INTEGER REFERENCES " + DB_Picture + " (" + DB_Picture_ID + ")";
	public  static final String DB_PictureSituation_Situation_ID = "picturesituation_situation_id";
	private static final String DB_PictureSituation_Situation_ID_ = "INTEGER REFERENCES " + DB_Situation + " (" + DB_Situation_ID + ")";
	public  static final String DB_PictureSituation_Position = "position";
	private static final String DB_PictureSituation_Postition_ = "INTEGER NOT NULL"; 
	public  static final String DB_PictureSituation_Active = "active";
	private static final String DB_PictureSituation_Active_ = "INTEGER NOT NULL";
	private static final String DB_PictureSituation_Unique_ = "UNIQUE (" + DB_PictureSituation_Position + ", " + DB_PictureSituation_Situation_ID + ")";
	private static final String DB_PictureSituation_Contraints_ = "CONSTRAINT 'integers_primary_key' PRIMARY KEY (" + DB_PictureSituation_Picture_ID + ", " + DB_PictureSituation_Situation_ID + ")";
	private static final String DB_PictureSituation_ = "CREATE TABLE " + DB_PictureSituation + " (" +
	  													  DB_PictureSituation_Picture_ID + " " + DB_PictureSituation_Picture_ID_ + ", " +
	  													  DB_PictureSituation_Situation_ID + " " + DB_PictureSituation_Situation_ID_ + ", " +
	  													  DB_PictureSituation_Position + " " + DB_PictureSituation_Postition_ + ", " +
	  													  DB_PictureSituation_Active + " " + DB_PictureSituation_Active_ + ", " +
	  													  DB_PictureSituation_Unique_ + ", " + DB_PictureSituation_Contraints_ + ");";
	
	// SQLite Database
	private SQLiteDatabase mDb;
    
    /**
	 * Constructor
	 * @param context - the context which to work within.
	 */
	public DBAdapter(Context context){
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}
	
	/**
	 * Run when the database should be create.
	 * 
	 * That is if application has never been used on the device before, or the whole database is dropped during an upgrade.
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		Log.i(LOG_TEXT, "Creating new database :");
		
		db.execSQL("PRAGMA foreign_keys=ON;");
		db.execSQL(DB_SentenceBoard_);
		db.execSQL(DB_Picture_);
		db.execSQL(DB_Situation_);
		db.execSQL(DB_PictureSituation_);
		db.execSQL("INSERT INTO " + DB_Situation + "(" + DB_Situation_ID + "," + DB_Situation_Name + ") values ("+ DEFAULT_SITUATION_LOCATION + ", 'Default');");
	}

	/**
	 * Run when the database is outdated, and thus have to be upgrade to a newer version.
	 * 
	 * Updates may be performed one version at a time. That is, if the database is being upgrade from version 2 to version 4, an upgrade may first be performed from version 2 to version 3. Afterwards the version 3 will be upgrade to the version 4.
	 * If the old version is not known, then all tables will be dropped and recreated. That is, all data will be lost.
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.i(LOG_TEXT, "Old version: " + oldVersion);
		db.execSQL("drop table if exists " + DB_SentenceBoard);
		db.execSQL("drop table if exists " + DB_Picture);
		db.execSQL("drop table if exists " + DB_Situation);
		db.execSQL("drop table if exists " + DB_PictureSituation);
		onCreate(db);
	}
	
	/**
	 * Opens the digiPECS database.
	 * 
	 * This has to be called before any data is accessible.
	 * 
	 * \see Example in \ref dbadapterexample "DBAdapter"
	 * 
	 * @throws SQLException The database could not be opened or created.
	 */
	public void open() throws SQLException{
		mDb = getWritableDatabase();
	}
	
	/**
	 * Closes the DigiPECS database.
	 * 
	 * Should be called when database access is finished.
	 * 
	 * \see Example in \ref dbadapterexample "DBAdapter"
	 */
	public void close(){
		//TODO The Database may still be commiting transaction at this time -- in this case exceptions is raised :(
		super.close();
	}
	
	// -------------------------------------------------------------------------
	// Queries concerning Situation table
	// - 
	// -------------------------------------------------------------------------
	public SituationCursor fetchSituations() {
		return SituationCursor.queryAll(mDb);
	}
	
	public SituationCursor fetchSituation(int sid) {
		return SituationCursor.query(mDb, sid);
	}
	
	public long addSituation(String name) throws DatabaseException {
		long status;
		ContentValues values = new ContentValues();
		values.put(DB_Situation_Name, name);
		
		status = mDb.insertOrThrow(DB_Situation, null, values);
		if (status < 0)
			throw new DatabaseException();
		else
			return status;
	}
	
	public void deleteSituation(int sid) {
		// Do not delete Default situation
		if(sid == 0) throw new NotSupportedException("Default situation (id 0) may not be deleted"); 
		
		// TODO This is hacked (because of problems with on delete cascade)
		mDb.beginTransaction();
		try {
			mDb.delete(DB_PictureSituation, DB_PictureSituation_Situation_ID + " = " + sid, null);
			mDb.delete(DB_Situation, DB_Situation_ID + " = " + sid, null);
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
	}
	
	public void setSituationName(int sid, String newName) throws DatabaseException{
		//Check default situation is not updated.
		if(sid != 0){
			ContentValues values = new ContentValues();
			values.put(DB_Situation_Name, newName);
			mDb.update(DB_Situation, values, DB_Situation_ID + " = " + sid, null);
		}
		else 
			throw new DatabaseException();
	}
	// -------------------------------------------------------------------------
	// Queries concerning Picture Situation table
	// -------------------------------------------------------------------------
	public IDCursor fetchActivePicturesForSituation(int sid) {
		return PictureSituationIDCursor.queryActiveForSituation(mDb, sid);
	}
	
	public IDCursor fetchAllPicturesForSituation(int sid) {
		return PictureSituationIDCursor.queryForSituation(mDb, sid);
	}
	
	public void addPictureToSituation(int pid, int sid) throws DatabaseException {
		final String column = "MAX(" + DB_PictureSituation_Position + ")";
		Cursor cursor = mDb.rawQuery("SELECT " + column + " FROM " + DB_PictureSituation + " WHERE " + DB_PictureSituation_Situation_ID + " = " + sid, null);
		int colIndex = cursor.getColumnIndexOrThrow(column);
		int position;
		
		if (cursor.moveToFirst()) {
			position = cursor.getInt(colIndex);
			position++;
		} else {
			throw new DatabaseException();
		}
		
		Log.i(LOG_TEXT, "position " + position + " (" + fetchAllPicturesForSituation(sid).getCount() + ")");
		long status;
		ContentValues values = new ContentValues();
		values.put(DB_PictureSituation_Picture_ID, pid);
		values.put(DB_PictureSituation_Situation_ID, sid);
		values.put(DB_PictureSituation_Active, TRUE);
		values.put(DB_PictureSituation_Position, position);
		
		status = mDb.insertOrThrow(DB_PictureSituation, null, values);
		if (status < 0)
			throw new SQLException();
	}
	
	public void removePictureFromSituation(int pid, int sid) {
		if(sid != 0)
			mDb.delete(DB_PictureSituation, DB_PictureSituation_Picture_ID + " = " + pid + " AND " + DB_PictureSituation_Situation_ID + " = " + sid, null);
	}
	/**
	 * Updates the active state from a cursor.
	 * 
	 * This is used in combination with fetchPicture(). This updates the truth value from the cursor, that is the active state of the picture.
	 * 
	 * @param pic_id An integer that uniquely identifies the picture that is updated.
	 * @param state An integer containing 0 or 1. 1 if the active state is true and 0 if the active state is false.
	 */
	public void setPictureActiveState (int pic_id, int situation_id, boolean state){
		final int activeState = ( state ? 1 : 0);
		ContentValues values = new ContentValues();
		
		values.put(DB_PictureSituation_Active, activeState);
		mDb.update(DB_PictureSituation, values, DB_PictureSituation_Picture_ID + " = " + pic_id + " AND " + DB_PictureSituation_Picture_ID + " = " + situation_id, null);
	}
	
	public void swapPicturePositionInSituation(int situation_id, int picture_id1, int picture_id2) throws IDNotFoundException {
		//TODO Thomas: Can the two get position parts be created within the transaction...
		int postion1, postion2;
		PictureActiveCursor psCursor;
		
		// Get position of picture 1
		psCursor = PictureActiveCursor.queryActive(mDb, picture_id1, situation_id);
		if (psCursor.moveToFirst()) { // TODO RIKKE had forgotten this check ;)
			postion1 = psCursor.getPicturePostion();
		} else {
			throw new IDNotFoundException();
		}
		
		// Get position of picture 2
		psCursor = PictureActiveCursor.queryActive(mDb, picture_id2, situation_id);
		if (psCursor.moveToFirst()) { // TODO RIKKE had forgotten this check ;)
			postion2 = psCursor.getPicturePostion();
		} else {
			throw new IDNotFoundException();
		}
		
		ContentValues values1 = new ContentValues();
		values1.put(DB_PictureSituation_Position, postion1);
		
		ContentValues values2 = new ContentValues();
		values2.put(DB_PictureSituation_Position, postion2);
		
		ContentValues valuesDummy = new ContentValues();
		valuesDummy.put(DB_PictureSituation_Position, 0);
		
		mDb.beginTransaction();
		try {
			// TODO Rikke got this a little bit wrong
			mDb.update(DB_PictureSituation, valuesDummy, DB_PictureSituation_Picture_ID + " = "+ picture_id2 + " AND " + DB_PictureSituation_Situation_ID + " = " + situation_id, null);
			mDb.update(DB_PictureSituation, values2, DB_PictureSituation_Picture_ID + " = "+ picture_id1 + " AND " + DB_PictureSituation_Situation_ID + " = " + situation_id, null);
			mDb.update(DB_PictureSituation, values1, DB_PictureSituation_Picture_ID + " = "+ picture_id2 + " AND " + DB_PictureSituation_Situation_ID + " = " + situation_id, null);
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
		
		
	}
	
	// -------------------------------------------------------------------------
	// Queries concerning Picture table
	// -------------------------------------------------------------------------
	/**
	 * Will fetch all pictures from the database table Picture and return a corresponding Cursor.
	 * 
	 * Will fetch all rows in the picture table with corresponding columns;picture_id, image_text, image_path, and active.
	 * \remark Remember to close the cursor, when it is no longer needed
	 * 
	 * @return A Cursor object, which is positioned before the first entry. This Cursor object will be associated with the database table of picture. 
	 */
	public IDCursor fetchPictures(){
		return PictureIDCursor.queryAll(mDb);
	}
	
	/**
	 * Will fetch all active pictures from the database table Picture and return a corresponding Cursor.
	 * 
	 * Will fetch all rows of active pictures in the picture table with corresponding columns;picture_id, image_text, and image_path.
	 * \remark Remember to close the cursor, when it is no longer needed
	 * 
	 * @return A Cursor object, which is positioned before the first entry. This Cursor object will be associated with the database table of picture. 
	 */
	/*public IDCursor fetchActivePictures() {
		return PictureSituationIDCursor.queryActive(mDb);
	}*/
	
	/**
	 * Will fetch one picture from the table Picture.
	 * 
	 * \remark Remember to close the cursor, when it is no longer needed
	 * 
	 * @param picture_id The picture_id of the image to be fetched from the database.
	 */
	public PictureCursor fetchPicture(int pic_id){
		return PictureCursor.query(mDb, pic_id);
	}
	
	public PictureActiveCursor fetchPictureActive(int pic_id, int situation_id) {
		return PictureActiveCursor.queryActive(mDb, pic_id, situation_id);
	}
	
	/**
	 * Will add a picture with corresponding text, sound and path to image being stored.
	 * 
	 * Used to add a image and corresponding data to the database table Pictures. The active state of the 
	 * picture will by default be set true;
	 *  
	 * @param imgTxt A string, containing the corresponding to the image being added to the database.
	 * @param imgPath A string, containing the path to the image being added to the database.
	 * @param soundPath A string, containing the path to the sound file being added to the database.
	 * @return The row ID of the newly inserted row.
	 * @throws SQLException Error when inserting values into the database.
	 * @throws DatabaseException 
	 */
	public long addPicture(String imgTxt, String imgPath, String soundPath) throws DatabaseException {
		long status;
		ContentValues values = new ContentValues();
		values.put(DB_Picture_ImageText, imgTxt);
		values.put(DB_Picture_ImagePath, imgPath);
		values.put(DB_Picture_ImageSound, soundPath);
		
		status = mDb.insertOrThrow(DB_Picture, null, values);
		
		
		addPictureToSituation((int)status, DEFAULT_SITUATION_LOCATION);
		
		if (status < 0)
			throw new DatabaseException();
		else
			return status;
	}
	
	/**
	 * Will remove a picture from the table Picture.
	 * 
	 * @param picture_id The picture_id of the image that will be removed from the database
	 * @return The number of rows affected by the query.
	 */
	public void deletePicture(int pic_id) {
		// TODO This is hacked (because of problems with on delete cascade)
		mDb.beginTransaction();
		try {
			mDb.delete(DB_SentenceBoard, DB_SentenceBoard_Picture_ID + " = " + pic_id, null);
			mDb.delete(DB_PictureSituation, DB_PictureSituation_Picture_ID + " = " + pic_id, null);
			mDb.delete(DB_Picture, DB_Picture_ID + " = " + pic_id, null);
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
	} 	
	
	/**
	 * Updates the text from a cursor.
	 * 
	 * This is used in combination with fetchPicture(). This updates the text from the cursor, that is the text to be put with the picture
	 * 
	 * @param pic_id An integer that uniquely identifies the picture that is updated.
	 * @param pic_text An String specifying the new text for the picture.
	 */
	public void setPictureText(int pic_id, String pic_text){
		ContentValues values = new ContentValues();
		values.put(DB_Picture_ImageText, pic_text);
		mDb.update(DB_Picture, values, DB_Picture_ID + " = " + pic_id, null);
		
	}	
	
	/**
	 * Updates the path from a cursor.
	 * 
	 * This is used in combination with fetchPicture(). This updates the path from the cursor, that is the location of the picture file.
	 * 
	 * @param pic_id An integer that uniquely identifies the picture that is updated.
	 * @param pic_path An String specifying the new path for the picture.
	 */
	public void setPicturePath(int pic_id, String pic_path){
		ContentValues values = new ContentValues();
		values.put(DB_Picture_ImagePath, pic_path);
		
		mDb.update(DB_Picture, values, DB_Picture_ID + " =  " + pic_id, null);
	}
	
	/**
	 * Updates the sound path from a cursor.
	 * 
	 * This is used in combination with fetchPicture(). This updates the sound path from the cursor, that is the location of the sound file associated with a picture.
	 * 
	 * @param pic_id An integer that uniquely identifies the picture that is updated.
	 * @param pic_path An String specifying the new path for the picture.
	 */
	public void setPictureSound(int pic_id, String sound__path){
		ContentValues values = new ContentValues();
		values.put(DB_Picture_ImageSound, sound__path);
		mDb.update(DB_Picture, values, DB_Picture_ID + " = " + pic_id, null);
	}
	
	// -------------------------------------------------------------------------
	// Queries concerning Sentence Board table
	// -------------------------------------------------------------------------
	/**
	 * Clears sentence board table.
	 * 
	 * Used before saving the state of the sentence board,
	 * to get a proper snapshot of the the
	 * current state, so no old data will interfere.
	 *  
	 * @return The number of rows affected by the 
	 * SQL query.
	 */
	public int clearSentenceBoardState(){
		return mDb.delete(DB_SentenceBoard, DB_SentenceBoard_Lock + " = " + FALSE, null);
	}
	// TODO Rikke: change KOMMENTAR.
	/**
	 * Saves the state of one picture, from the sentence board.
	 *  
	 * The data is saved in the sentence board table, and will later before used to restore the state of the sentence board.
	 * 
	 * @param index The location of the picture, within the sentence board.
	 * @param image A container containing all information of the picture.
	 * @return The row ID of the newly inserted row or row ID of the existing row, if it already exists.
	 * @throws SQLException Error when inserting values into the database.
	 */
	public void saveSentenceBoardStateItem(int index, int pic_id) throws SQLException {
		// TODO Consider doing this as transaction as well...
		long status;
		
		Log.i(LOG_TEXT, "getting sentenceboard cursor");
		SentenceBoardStateCursor cursor = SentenceBoardStateCursor.queryIndex(mDb, index);
		
		
		Log.i(LOG_TEXT, "test " + cursor.getCount());
		if(cursor.getCount() > 0) return;
	
		Log.i(LOG_TEXT, "About to save");
		ContentValues values = new ContentValues();
		values.put(DB_SentenceBoard_Index, index);
		values.put(DB_SentenceBoard_Picture_ID, pic_id);
		values.put(DB_SentenceBoard_Lock, FALSE);
		
		
		status = mDb.insertOrThrow(DB_SentenceBoard, null, values);
		
		if (status < 0)
			throw new SQLException();
	}
	//TODO RIKKE MANGLER KOMMENTAR
	public void setLockedSentenceBoardItem(int index, int pic_id, boolean lock) {
		final int locked = ( lock ? TRUE : FALSE);
		
		mDb.delete(DB_SentenceBoard, DB_SentenceBoard_Index + " = " + index, null);
		
		ContentValues values = new ContentValues();
		values.put(DB_SentenceBoard_Index, index);
		values.put(DB_SentenceBoard_Picture_ID, pic_id);
		values.put(DB_SentenceBoard_Lock, locked);
		mDb.insertOrThrow(DB_SentenceBoard, null, values);
	}
	
	/**
	 * Fetch data associated with the last saved state of the sentence board.
	 * 
	 * This is used to restore the sentence board back to previous saved state.
	 * \remark Remember to close the cursor, when it is no longer needed
	 * 
	 * @return A Cursor object, which is positioned before the first entry. This Cursor object will be associated with the database table of the sentence board. 
	 */
	public SentenceBoardStateCursor fetchSentenceBoardAllItems() {
		return SentenceBoardStateCursor.queryAll(mDb);
	}

	public SentenceBoardStateCursor fetchSentenceBoardItem(int index) {
		return SentenceBoardStateCursor.queryIndex(mDb, index);
	}

	
	
}
